package com.free.ext.quartz.tasker;

import com.free.exception.SystemRuntimeException;
import com.free.ext.logger.FreeLogger;
import com.free.ext.logger.FreeLoggerFactory;
import com.free.ext.quartz.functional.FunctionRunTask;
import com.free.ext.quartz.model.ConcurrentTaskEnum;
import com.free.ext.quartz.model.TaskRes;
import com.free.ext.quartz.model.TaskStatusEnum;

import java.util.function.Consumer;



/**
 * <p>
 * 功能概述: 
 * </p>
 * <p>
 * 功能详述: 
 * </p>
 */
public abstract class Tasker implements ITasker
{

    /*========================================================================*
     *                         Public Fields (公共属性)                                                                
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)                                                                
     *========================================================================*/

    private static final FreeLogger logger = FreeLoggerFactory.getLogger(Tasker.class);

    private String groupNm;

    private String taskNm;

    private String cronExperssion;

    private String description;

    private volatile TaskStatusEnum status = TaskStatusEnum.FREE;

    private Consumer<TaskRes> callback;

    private ConcurrentTaskEnum isConcurrent;


    /*========================================================================*
     *                         Construct Methods (构造方法) 
     *========================================================================*/

    /**
     * @return the groupNm
     */
    public String getGroupNm()
    {
        return groupNm;
    }


    /**
     * @param groupNm the groupNm to set
     */
    public void setGroupNm(String groupNm)
    {
        this.groupNm = groupNm;
    }


    /**
     * @return the taskNm
     */
    public String getTaskNm()
    {
        return taskNm;
    }


    /**
     * @param taskNm the taskNm to set
     */
    public void setTaskNm(String taskNm)
    {
        this.taskNm = taskNm;
    }


    /**
     * @return the cornExperssion
     */
    public String getCronExperssion()
    {
        return cronExperssion;
    }


    /**
     * @param cronExperssion the cornExperssion to set
     */
    public void setCronExperssion(String cronExperssion)
    {
        this.cronExperssion = cronExperssion;
    }


    /**
     * @return the description
     */
    public String getDescription()
    {
        return description;
    }


    /**
     * @param description the description to set
     */
    public void setDescription(String description)
    {
        this.description = description;
    }


    /**
     * @return the status
     */
    public TaskStatusEnum getStatus()
    {
        return status;
    }


    /**
     * @param status the status to set
     */
    public void setStatus(TaskStatusEnum status)
    {
        this.status = status;
    }


    /**
     * @return the callback
     */
    public Consumer<TaskRes> getCallback()
    {
        return callback;
    }


    /**
     * @param callback the callback to set
     */
    public void setCallback(Consumer<TaskRes> callback)
    {
        this.callback = callback;
    }


    /**
     * @return the isConcurrent
     */
    public ConcurrentTaskEnum getIsConcurrent()
    {
        return isConcurrent;
    }


    /**
     * @param isConcurrent the isConcurrent to set
     */
    public void setIsConcurrent(ConcurrentTaskEnum isConcurrent)
    {
        this.isConcurrent = isConcurrent;
    }


    public TaskRes executeProc(FunctionRunTask c)
    {
        if (this.getStatus() == TaskStatusEnum.PAUSE)
        {
            String msg = String.format("任务 组:%s 名称:%s ,当前状态是%s,任务被阻止", this.getGroupNm(), this.getTaskNm(), this.getStatus().toString());
            logger.error(msg);
            throw new SystemRuntimeException("任务运行时发生异常", msg);
        }
        this.setStatus(TaskStatusEnum.RUNNING);

        logger.info("任务 {},{} 开始执行", this.getGroupNm(), this.getTaskNm());

        TaskRes res;

        try
        {
            res = c.run();
            logger.info("任务 {},{} 执行成功 结果:{}", this.getGroupNm(), this.getTaskNm(), res.getData());
        }
        catch (Throwable t)
        {
            logger.error("任务 {},{} 发生异常 err:{}", this.getGroupNm(), this.getTaskNm(), t.getMessage());
            res = TaskRes.error(t.getMessage());
        }
        finally
        {
            this.setStatus(TaskStatusEnum.FREE);
        }

        res.setJobGroup(this.getGroupNm());
        res.setJobName(this.getTaskNm());
        if (this.getCallback() != null)
        {
            this.getCallback().accept(res);
        }
        return res;
    }

    /*========================================================================*
     *                         Public Methods (公有方法)                                                                   
     *========================================================================*/

    /*========================================================================*
     *                         Private Methods (私有方法)                                                                   
     *========================================================================*/
}
